﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using EITSurferInfinityLib;
using EITSurferInfinityLib.DataProcessing;
using System.Threading;
using System.IO;
using System.Windows.Interop;

namespace WpfApplication1
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        VirtualDevice Device;
        string MessageBuffer;
        SimpleData SimpleDataLast;
        bool SimpleDataLastRead;
        bool ReconstructedImageDisplayed;
        bool StartTrigger;
        bool RawMode;
        WHostParameter dialogSettings;
        SlimDxWindow sdxw;
        GraphModeSettings ZedGraphSettings;
        AlertWindows aw;
        ContactElectrodeWindow contactWindow;
        WindowSerial windowsSerial;
        WindowSelectHw windowsSelectHw;

        public MainWindow()
        {
            InitializeComponent();
            string [] temp=System.IO.File.ReadAllLines(@"hardware settings\user\lastdevice.txt");
            if (temp[0] != "")
            {
                InitializeNewDevice(temp[0]);
            }
            else
            { 
                InitializeNewDevice("st_1_0.111_2.42_B");
            }
        }

        private void InitializeNewDevice(string name)
        {

            Device = new VirtualDevice(name);
            string[] temp = new string[1];
            temp[0] = name;
            System.IO.File.WriteAllLines(@"hardware settings\user\lastdevice.txt", temp);


            this.richTextBoxOut.SetValue(Paragraph.LineHeightProperty, 1.0);

            MessageBuffer = "";
            SimpleDataLastRead = true;
            ReconstructedImageDisplayed = true;
            StartTrigger = false;
            RawMode = false;

            ZedGraphSettings = GraphModeSettings.Normal;

            //wire events
            Device.OnMessage += new VirtualDevice.OnMessageHandler(Device_OnMessage);
            Device.OnSimpleData += new VirtualDevice.OnSimpleDataHandler(Device_OnSimpleData);
            Device.OnRawData += new VirtualDevice.OnRawDataHandler(Device_OnRawData);
            Device.OnConnected += new VirtualDevice.OnConnectedHandler(Device_OnConnected);
            Device.OnReconstructedImage += new VirtualDevice.OnReconstructedImageHandler(Device_OnReconstructedImage);
        }

        private void OnIdle(object sender, EventArgs e)
        {
            if (Device != null)
            {
                this.Dispatcher.Invoke((Action)(() =>
                {
                    labelFrameCounter.Content = Device.FrameCounter.ToString();
                }));
            }
            if (MessageBuffer != "")
            {
                this.Dispatcher.Invoke((Action)(() =>
                {
                    richTextBoxOut.AppendText(MessageBuffer);
                    MessageBuffer = "";
                    this.richTextBoxOut.ScrollToEnd();
                }));
                
            }
            if (ReconstructedImageDisplayed==false)
            {
                if ((sdxw != null) && (Device.LastImage != null))
                {
                    ReconstructedImageDisplayed = true;
                    sdxw.sdxc.Update(Device.LastImage, false, Device.GetFilePlayerCounter());
                }
            }
            if (SimpleDataLastRead == false)
            {
                this.Dispatcher.Invoke((Action)(() =>
                {
                    if (SimpleDataLast != null)
                    {
                        SimpleDataLastRead = true;
                        double[] d = IQDataProcessor.GetAmplitude(SimpleDataLast.I, SimpleDataLast.Q,Device.ToVoltParameter);
                        double[] dd = IQDataProcessor.RemoveInjectionElectrode(d,Device.Offset,32);
                        zedGraphWPF1.ClearAllCurves();
                        zedGraphWPF1.CreatePlot(dd);
                        zedGraphWPF1.Refresh();


                        zedGraphWPF2.UpDateRollingPlot(IQDataProcessor.Mean(d),100);

                        //double CurrentA = (4.096 / 256.0) * 150.0/390;
                        //Device.ToVoltParameter.CurrentA = CurrentA;

                        double[] d2 = Device.GetComplexImpedance(SimpleDataLast.I2, SimpleDataLast.Q2);
                            //IQDataProcessor.GetComplexImpedance(SimpleDataLast.I2, SimpleDataLast.Q2, Device.ToVoltParameter, Device.Frequency);
                        zedGraphWPF3.CreateBarPlot(d2);
                        zedGraphWPF3.Refresh();

                        if (contactWindow != null)
                        {
                            if (contactWindow.Visibility== Visibility.Visible)
                            {
                                contactWindow.electrodeContactControler1.UpdateElectrodeState(d2, Device.Offset);
                            }
                        }

                        double[] d3 = IQDataProcessor.GetPhase(SimpleDataLast.I2, SimpleDataLast.Q2, Device.ToVoltParameter);
                        zedGraphWPF4.CreateBarPlot(d3);
                        zedGraphWPF4.Refresh();
                    }
                }));
            }
        }

        private void UpdateGraphTitle()
        {
            zedGraphWPF1.SetTitles(GraphMode.GetGraphTitlesByMode("GraphText.txt", ZedGraphSettings, 0));
            zedGraphWPF2.SetTitles(GraphMode.GetGraphTitlesByMode("GraphText.txt", ZedGraphSettings, 1));
            zedGraphWPF3.SetTitles(GraphMode.GetGraphTitlesByMode("GraphText.txt", ZedGraphSettings, 2));
            zedGraphWPF4.SetTitles(GraphMode.GetGraphTitlesByMode("GraphText.txt", ZedGraphSettings, 3));

            zedGraphWPF1.Refresh();
            zedGraphWPF2.Refresh();
            zedGraphWPF3.Refresh();
            zedGraphWPF4.Refresh();
        }



        private void ButtonDisconnect_Click(object sender, RoutedEventArgs e)
        {
            Device.Stop();
            Thread.Sleep(100);
            Device.Disconnect(); 
        }

        private void buttonTest_Click(object sender, RoutedEventArgs e)
        {
            if (Device.IsConnected())
            {
                this.richTextBoxOut.AppendText("connected\n");
            }
            //Device.Test();
            this.richTextBoxOut.AppendText(Device.Test()+'\n');
            this.richTextBoxOut.ScrollToEnd();
            //this.textBlockOutput.Device.Test());
        }

        private void buttonStart_Click(object sender, RoutedEventArgs e)
        {
            Device.Stop();
            string[] revisions = Device.DeviceName.Split('_');
            string s = revisions[2].Replace(".", "p");
            //ParamManager.ProgramParameter(@"hardware settings\swisstom\DefaultParameter_" + s + ".txt", ref Device);
            ProgrammParameter();
            if (RawMode == true)
            {
                RawMode = false;
                zedGraphWPF1.ClearAllCurves();
                zedGraphWPF2.ClearAllCurves();
                zedGraphWPF2.ReconnectRollingPairList();
            }
            Device.Start();
        }

        private void buttonStop_Click(object sender, RoutedEventArgs e)
        {
            Device.Stop();
        }

        #region EventHandling

        private void Device_OnMessage(object sender, EventArgsMsg e)
        {
            if (e.Sender.Contains("Open Alert"))
            {
                aw = new AlertWindows(e.Message);
                aw.Show();
            }

            if (e.Sender.Contains("Close Alert"))
            {
                if(aw.IsVisible)
                    aw.Close();
            }

            SetTextMessage(e.Message); //call to thread-safe methode
        }
        private bool IsDeviceStart(string msg)
        {
            msg.Contains("");
            return true;
        }
        private void Device_OnSimpleData(object sender, EventArgsSimpleData e)
        {
            //SetTextMessage(e.data.I2[0].ToString()+'\n');
            //richTextBoxOut.AppendText(e.data.I2[0].ToString());

            //double[] d = IQDataProcessor.GetAmplitude(e.data.I, e.data.Q);
            //SetTextMessage(d[0].ToString()+'\n');

            this.Dispatcher.Invoke((Action)(() =>
            {
                SimpleDataLastRead = false;
                SimpleDataLast=e.data;
            }));
        }
        private void SetTextMessage(string text)
        {
           this.Dispatcher.Invoke((Action)(() =>
            {
                MessageBuffer += text;
                //richTextBoxOut.AppendText(text);
            }));

        }

        #endregion

        private void buttonProgramParam_Click(object sender, RoutedEventArgs e)
        {
            ZedGraphSettings = GraphModeSettings.Normal;
            UpdateGraphTitle();

            if (!Device.IsConnected())
            {
                StartTrigger = true;
                Device.Connect();
            }
            else
            {
                if (Device.IsStopped == false)
                {
                    Device.Stop();
                }
                else
                {
                    string[] revisions = Device.DeviceName.Split('_');
                    string s = revisions[2].Replace(".", "p");
                    //ParamManager.ProgramParameter(@"hardware settings\swisstom\DefaultParameter_" + s + ".txt", ref Device);
                    ProgrammParameter();
                    if (RawMode == true)
                    {
                        RawMode = false;
                        zedGraphWPF1.ClearAllCurves();
                        zedGraphWPF2.ClearAllCurves();
                        zedGraphWPF2.ReconnectRollingPairList();
                    }
                    //Thread.Sleep(100); // for the buffer to be empty
                    Device.Start();
                }
            }
        }


        private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            if (Device != null)
            {
                Device.Stop();
                Device.Disconnect();
            }
            if (sdxw != null)
            {
                sdxw.Close();
            }
            if (dialogSettings != null)
            {
                dialogSettings.Close();
            }
            
            ComponentDispatcher.ThreadIdle -= new EventHandler(OnIdle);
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            //wire Events
            
            ComponentDispatcher.ThreadIdle += new EventHandler(OnIdle);
        }
        private void Device_OnReconstructedImage(Object sender, EventArgs e)
        {
            ReconstructedImageDisplayed = false;
            //if ((sdxw != null) && (Device.LastImage != null))
            //{
            //    if (Device.GetReplayMode() == PlayerStates.Streaming)
            //    {
            //        sdxw.sdxc.Update(Device.LastImage, false);
            //    }
            //    else
            //    {
            //        sdxw.sdxc.Update(Device.LastImage, true);
            //    }
            //}
        }
        private void Device_OnConnected(Object sender, EventArgs e)
        {
            if (StartTrigger)
            {
                 buttonProgramParam_Click(null, null);
            }
        }
        private void Device_OnRawData(Object sender, EventArgsRawData e)
        {
            zedGraphWPF1.ClearAllCurves();
            zedGraphWPF2.ClearAllCurves();
            zedGraphWPF1.CreatePlot(RawDataProcessing.IntTodouble(e.data.Signal1));
            zedGraphWPF2.CreatePlot(RawDataProcessing.IntTodouble(e.data.Signal2));
            zedGraphWPF1.Refresh();
            zedGraphWPF2.Refresh();
        }
        private void buttonRaw_Click(object sender, RoutedEventArgs e)
        {
            Device.Stop();
            ZedGraphSettings = GraphModeSettings.Raw;
            UpdateGraphTitle();
            Device.Send("Stop");
            //ParamManager.ProgramParameter("DefaultParameter.txt", ref Device);
            Thread.Sleep(100);
            RawMode = true;
            Device.Send("Raw");
        }

        private void button1_Click(object sender, RoutedEventArgs e)
        {
            Device.ConnectP2P();
        }

        private void button2_Click_1(object sender, RoutedEventArgs e)
        {
            Device.Stop();
            ProgrammParameter();
            //ParamManager.ProgramParameterByName("CurrentParameter.txt", "PGA0_G", "0", ref Device);
            //Device.Send("set PGA0_G 0");
            Device.Start();
        }

        private void button3_Click(object sender, RoutedEventArgs e)
        {
            Device.Stop();
            ProgrammParameter();
            //ParamManager.ProgramParameterByName("CurrentParameter.txt", "PGA0_G", "1", ref Device);
            //Device.Send("set PGA0_G 1");
            Device.Start();
        }

        private void button4_Click(object sender, RoutedEventArgs e)
        {
            Device.Stop();
            ProgrammParameter();
            //ParamManager.ProgramParameterByName("CurrentParameter.txt", "PGA1_G", "0", ref Device);
            //Device.Send("set PGA1_G 0");
            Device.Start();
        }

        private void button5_Click(object sender, RoutedEventArgs e)
        {
            Device.Stop();
            ProgrammParameter();
            //ParamManager.ProgramParameterByName("CurrentParameter.txt", "PGA1_G", "1", ref Device);
            //Device.Send("set PGA1_G 1");
            Device.Start();
        }

        private void button6_Click(object sender, RoutedEventArgs e)
        {
            zedGraphWPF2.ClearAllCurves();
        }

        private void buttonHWSettings_Click(object sender, RoutedEventArgs e)
        {
            //todo: open a win with options
            if ((dialogSettings == null) || (dialogSettings.IsVisible==false))
            {
                dialogSettings = new WHostParameter(ref Device, "settings");
            }
            dialogSettings.Show();
            dialogSettings.BringIntoView() ;
            dialogSettings.Activate();
        }

        private void button7_Click(object sender, RoutedEventArgs e)
        {
            zedGraphWPF3.SetTitle("Impedance");
            zedGraphWPF3.SetXAxisTitle("Index");
            zedGraphWPF3.SetYAxisTitle("Impedance [Ohm]");
            zedGraphWPF3.Refresh();
        }

        private void GetInfo_Click(object sender, RoutedEventArgs e)
        {
            DeviceInfo di = Device.GetInfo();
            richTextBoxOut.AppendText("Device Information\n");
            richTextBoxOut.AppendText("----------------------------\n");
            richTextBoxOut.AppendText("Manufacturer: " + di.Manufacturer + "\n");
            richTextBoxOut.AppendText("Name: " + di.DeviceName + "\n");
            richTextBoxOut.AppendText("Firmware: " + di.FirmwareVersion + "\n");
            richTextBoxOut.AppendText("Data protocol code: " + di.Protocol + "\n");
            richTextBoxOut.AppendText("IP Address: " + di.IPAddress + "\n");
            richTextBoxOut.AppendText("----------------------------\n");
            this.richTextBoxOut.ScrollToEnd();
        }

        private void button8_Click(object sender, RoutedEventArgs e)
        {
            Device.Send("Stop");
            //ParamManager.ProgramParameter("DefaultParameter.txt", ref Device);
            Thread.Sleep(100);
            RawMode = true;
            Device.SerialRaw(50);
        }

        private void buttonProtocol_Click(object sender, RoutedEventArgs e)
        {
            WHostParameter dialog = new WHostParameter(ref Device, "protocol");
            dialog.Show();
        }

        private void buttonEnableRecord_Click(object sender, RoutedEventArgs e)
        {
            if (Device.EnableRecordFrames == false)
            {
                Device.EnableRecordFrames = true;
                SolidColorBrush myBrush = new SolidColorBrush(Colors.Orange);
                //buttonEnableRecord.Background = myBrush;
                //buttonEnableRecord.Content = "Disable Recording";
            }
            else
            {
                Device.EnableRecordFrames = false;
                SolidColorBrush myBrush = new SolidColorBrush(Colors.Blue);
                //buttonEnableRecord.Background = myBrush;
                //buttonEnableRecord.Content = "Enable Recording";
            }
        }

        private void buttonReconstruction_Click(object sender, RoutedEventArgs e)
        {
            if (!File.Exists("Shaders\\SimpleRendering.fx"))
            {
                File.Copy("SimpleRendering.fx", "Shaders\\SimpleRendering.fx");
            }
            Device.EnableReconstruction += 1;
            sdxw = new SlimDxWindow(ref Device);
            sdxw.Show();
        }

        private void buttonIconDisconnect_Click(object sender, RoutedEventArgs e)
        {
            Device.Stop();
            Thread.Sleep(100);
            Device.Disconnect(); 
        }

        private void buttonIconReplayPlay_Click(object sender, RoutedEventArgs e)
        {
            if (!File.Exists("Shaders\\SimpleRendering.fx"))
            {
                File.Copy("SimpleRendering.fx", "Shaders\\SimpleRendering.fx");
            }
            Device.EnableReconstruction += 1;
            sdxw = new SlimDxWindow(ref Device);
            sdxw.Show();

            ZedGraphSettings = GraphModeSettings.Normal;
            UpdateGraphTitle();
            sdxw.sdxc.LoadHistory();
        }

        private void buttonIconReplayStop_Click(object sender, RoutedEventArgs e)
        {
            Device.StopReplay();
        }

        private void OpenContactElectrode_Click(object sender, RoutedEventArgs e)
        {
            contactWindow = new ContactElectrodeWindow();
            contactWindow.Show();
        }

        private void SaveToFile_Click(object sender, RoutedEventArgs e)
        {
            Device.SaveDataToFile();
        }

        private void Serial_Click(object sender, RoutedEventArgs e)
        {
            windowsSerial = new WindowSerial(ref Device);
            windowsSerial.Show();
        }

        private void SelctHw_Click(object sender, RoutedEventArgs e)
        {
            
            windowsSelectHw = new WindowSelectHw();
            windowsSelectHw.ShowDialog();

            InitializeNewDevice(windowsSelectHw.hw_name);
        }


        private void ProgrammParameter()
        {
            switch(Device.DeviceName)
            {
                case "st_1_0.12_3.0_A":
                    Param_st_1_0p12.ProgramParameter(@"hardware settings\swisstom\DefaultParameter_0p12.txt", ref Device);
                    break;
                case "st_1_0.12_3.0_B":
                    Param_st_1_0p12.ProgramParameter(@"hardware settings\swisstom\DefaultParameter_0p12.txt", ref Device);
                    break;
                case "st_1_0.111_2.42_B":
                    Param_st_1_0p111.ProgramParameter(@"hardware settings\swisstom\DefaultParameter_0p111.txt", ref Device);
                    break;
            }

        }

        private void ClearData_Click(object sender, RoutedEventArgs e)
        {
            Device.Clear();
        }

        private void Reset_Click(object sender, RoutedEventArgs e)
        {
            Device.Stop();
            Device.Disconnect();
            Thread.Sleep(200);
            string[] temp = System.IO.File.ReadAllLines(@"hardware settings\user\lastdevice.txt");
            if (temp[0] != "")
            {
                InitializeNewDevice(temp[0]);
            }
        }




}
}
